/**************************************************************
 * @file     app_uart_parse.c
 * @brief    串口解析APP层，接收串口数据就绪的通知，进行串口数据解析
 * @author   Ruilist
 * @date     2025-08-11
 * @version  V1.0.0
 * @copyright Copyright (c) 2025
 *
 * @note     1 tab = 4 space
 *
 *
 * @par 日志:
 * - V1.0.0 2025-08-11 Ruilist
 *   接收串口数据就绪的通知，进行串口数据解析
 **************************************************************/

//******************************** Includes *********************************//
#include "app_uart_parse.h"
//******************************** Includes *********************************//

//******************************** Defines **********************************//

osThreadId_t app_uart_parse_TaskHandle = NULL;

const osThreadAttr_t app_uart_parse_attributes = {
    .name       = "app_uart_parse_Task",
    .stack_size = 128 * 5,
    .priority   = (osPriority_t)osPriorityNormal,
};

circular_buffer_t *p_app_uart_buffer = NULL;  // 环形缓冲区指针

#define FRAMFRAME_FIND_HEAD ( 0x00 )
#define FRAMFRAME_LENGTH    ( 0x01 )
#define FRAMFRAME_DATA      ( 0x02 )
#define FRAMFRAME_CHECK     ( 0x03 )
#define FRAMFRAME_END       ( 0x04 )

#define FRAMFRAME_HEAD      ( 0xAA )
#define FRAMFRAME_TAIL      ( 0x55 )

//******************************** Defines **********************************//

//*********************Thread_Func **********************//

//*********************Thread_Func **********************//

//*********************Queue_Handler ********************//

SemaphoreHandle_t bsp_to_parse_count = NULL;

//*********************Queue_Handler ********************//

//******************************** Declaring ********************************//

void app_uart_parse_Task_func( void *argument )
{
    log_i( "app uart parse Task start \r\n" );

    osDelay( 10 );

    bsp_to_parse_count = xSemaphoreCreateCounting( 4, 0 );
    if ( NULL == bsp_to_parse_count )
    {
        log_e( "bsp_to_parse_count created failed\r\n" );
        return;
    }

    if ( CIRCULAR_BUFFER_OK != bsp_get_buffer_address( &p_app_uart_buffer ) )
    {
        log_e( "app uart get_buffer_address error\r\n" );
    }
    log_i( "p_app_uart_buffer is[%p] \r\n", p_app_uart_buffer );

    for ( ;; )
    {
        if ( pdTRUE == xSemaphoreTake( bsp_to_parse_count, portMAX_DELAY ) )
        {
            log_i( "app uart parse Task xSemaphoreTake successfully \r\n" );
            // log_i( "receive_data is [%d]", p_app_uart_buffer->data[(p_app_uart_buffer->head) - 1] );

            if ( NULL == p_app_uart_buffer )
            {
                log_e( "p_app_uart_buffer error \r\n" );
                return;
            }

            uint8_t        temp_data           = 0;
            static uint8_t temp_data_array[20] = { 0x00 };

            while ( CIRCULAR_BUFFER_OK == read_circular_buffer( p_app_uart_buffer, &temp_data ) )
            {
                static uint32_t status       = FRAMFRAME_FIND_HEAD;
                static uint32_t data_length  = 0;
                static uint32_t array_length = 0;

                uint32_t data_sum = 0;

                switch ( status )
                {
                case FRAMFRAME_FIND_HEAD:
                    if ( FRAMFRAME_HEAD == temp_data )
                    {
                        status = FRAMFRAME_LENGTH;
                        log_i( "find head\r\n" );
                    }
                    break;

                case FRAMFRAME_LENGTH:
                    data_length = temp_data;
                    status      = FRAMFRAME_DATA;
                    log_i( "data_length is[%d]\r\n", data_length );
                    break;

                case FRAMFRAME_DATA:
                    if ( array_length < data_length )
                    {
                        temp_data_array[array_length] = temp_data;
                        if ( array_length + 1 == data_length )
                        {
                            status = FRAMFRAME_CHECK;
                        }
                        else
                        {
                            status = FRAMFRAME_DATA;
                        }
                        array_length++;
                    }
                    break;
                case FRAMFRAME_CHECK:
                    array_length = 0;
                    for ( uint8_t i = 0; i < data_length; i++ )
                    {
                        log_i( "temp_data_array[%d] is[%x]\r\n", i, temp_data_array[i] );
                        data_sum += temp_data_array[i];
                    }
                    log_i( "data_sum is[%d]\r\n", data_sum );
                    if ( temp_data == data_sum )
                    {
                        log_i( "data check ok\r\n" );
                    }
                    else
                    {
                        log_w( "data check error\r\n" );
                        log_i( "temp_data is[%x]\r\n", temp_data );
                    }
                    status = FRAMFRAME_END;
                    break;
                case FRAMFRAME_END:
                    if ( FRAMFRAME_TAIL == temp_data )
                    {
                        log_i( "FRAMFRAME over\r\n" );
                    }
                    else
                    {
                        log_w( "FRAMFRAME end error\r\n" );
                    }
                    status = FRAMFRAME_FIND_HEAD;
                    break;
                default:
                    break;
                }
            }
        }
    }
}

//******************************** Declaring ********************************//
